﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
namespace XYZshell.Game.CardGameEngine
{
	/// <summary>
	/// 卡牌抽象类
	/// </summary>
	[Serializable]
	[XmlRoot("Card")]
	public abstract   class BaseCard:GameObject,IXMLable,IXmlSerializable
	{
		/// <summary>
		/// 构造函数
		/// </summary>
		public BaseCard()
		{
			Properties = new Dictionary<string, string>();
			Affect = new Affect();
		}
		/// <summary>
		/// 属性词典集合
		/// </summary>
		public  Dictionary<string, string> Properties
		{
			get;
			set;
		}
		/// <summary>
		/// 卡片的效果
		/// </summary>
		public Affect Affect
		{
			get;
			set;
		}

		#region IXMLable 成员
		/// <summary>
		/// 转换为XML
		/// </summary>
		/// <returns></returns>
		public string ToXML()
		{
			StringBuilder sb=new StringBuilder();
			sb.AppendLine( "<Card xmlns=\"http://game.xyzshell.org/OpenCG/Card\">" );
			sb.Append( GetXMLContent() );
			sb.AppendLine("</Card>");
			return sb.ToString();
		}
		protected string GetXMLContent()
		{
			StringBuilder sb=new StringBuilder();
			sb.AppendLine( "<properties>" );
			foreach (KeyValuePair<string,string> p in Properties)
			{
				sb.AppendFormat( "<property name=\"{0}\" value=\"{1}\"/>\r\n", p.Key, p.Value );
			}
			sb.AppendLine( "</properties>" );
			sb.Append( Affect.ToXML() );
			return sb.ToString();
		}
		/// <summary>
		/// 从XML中生成卡牌
		/// </summary>
		/// <param name="xmlNode"></param>
		/// <returns></returns>
		public static  Card FromXML( string xmlNode )
		{
			Card card=new Card();

			XObject xo=new XObject( xmlNode );
			string file=xo.Attribute( "file" );
			if (file != null)
			{
				card = BaseCard.FromFile( file );
			}
			else
			{
				XObject[] childs=xo.Childs;
				foreach (XObject x in childs)
				{
					switch (x.NodeName)
					{
						case "properties":
							{
								XObject xprops=new XObject( x.OuterXml );
								foreach (XObject xprop in xprops.Childs)
								{
									card.Properties.Add( xprop.Name, xprop.Value );
								}
							}
							break;
						case "affect":
							card.Affect = Affect.FromXML( x.OuterXml );
							break;
					}
				}
			}
			return card;
		}

		#endregion

		/// <summary>
		/// 从文件中读取卡片
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public static Card FromFile( string path )
		{
			string xml=File.ReadAllText( path );
			return Card.FromXML( xml );
		}
		/// <summary>
		/// 保存到文件
		/// </summary>
		/// <param name="xmlPath"></param>
		public  void Save( string xmlPath )
		{
			XObject x=new XObject( this.ToXML() );
			XmlDocument doc=new XmlDocument();
			doc.LoadXml( x.ToXml );
			//XmlWriter xw= XmlWriter.Create(xmlfn  );
			//doc.WriteContentTo( xw );
			//xw.Flush();
			doc.Save( xmlPath );
		}

		#region IXmlSerializable 成员

		public System.Xml.Schema.XmlSchema GetSchema()
		{
			//StreamReader sr=new StreamReader(CardGameEngine.Properties.Resources.card);

			//XmlSchema schema=XmlSchema.Read( sr, null );
			//return schema;
			throw new NotImplementedException();
		}

		public void ReadXml( XmlReader reader )
		{
			//string xml=reader.ReadInnerXml();

			XObject xo=new XObject( reader.ReadOuterXml() );
			string file=xo.Attribute("file");
			if (file != null)
			{
				Card c=Card.FromFile( file );
				Properties = c.Properties;
				Affect = c.Affect;
			}
			else
			{

				XObject[] childs=xo.Childs;
				foreach (XObject x in childs)
				{
					switch (x.NodeName)
					{
						case "properties":
							{
								XObject xprops=new XObject( x.OuterXml );
								foreach (XObject xprop in xprops.Childs)
								{
									Properties.Add( xprop.Name, xprop.Value );
								}
							}
							break;
						case "affect":
							Affect = Affect.FromXML( x.OuterXml );
							break;
					}
				}
			}
		}

		public void WriteXml( XmlWriter writer )
		{


			writer.WriteRaw( GetXMLContent() );

		}

		#endregion
	}
}
